package com.sanhe.rfmuscle.util;

import static com.menu.app.util.port.SerialHandle.byte2int;
import static com.menu.app.util.port.SerialHandle.byteToHex;

import android.content.Intent;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import com.menu.app.MyApp;
import com.menu.app.event.StartEvent;
import com.menu.app.model.Models;
import com.menu.app.util.FunctionCode;
import com.menu.app.util.Utils;
import com.menu.app.util.port.SerialHandler;
import com.menu.app.util.port.SerialManage;
import com.plata.base.aclr.utils.SPHelper;
import com.plata.base.utils.WeakHandler;
import com.sanhe.rfmuscle.App;
import com.sanhe.rfmuscle.activity.work.CardActivity;
import com.sanhe.rfmuscle.activity.work.ConfigActivity;
import com.sanhe.rfmuscle.activity.work.FlowActivity;
import com.sanhe.rfmuscle.activity.work.ModeActivity;
import com.sanhe.rfmuscle.activity.work.PwdActivity;
import com.sanhe.rfmuscle.activity.work.RentActivity;
import com.sanhe.rfmuscle.activity.work.SettingActivity;
import com.sanhe.rfmuscle.activity.work.TempActivity;
import com.sanhe.rfmuscle.activity.work.VrefActivity;
import com.sanhe.rfmuscle.activity.work.WarnActivity;
import com.sanhe.rfmuscle.activity.work.WireActivity;
import com.sanhe.rfmuscle.activity.work.WorkActivity;
import com.sanhe.rfmuscle.event.Event;

import java.util.ArrayList;
import java.util.List;

public class MySerialHandler implements SerialHandler {

    WeakHandler h = new WeakHandler(Looper.getMainLooper());

    @Override
    public int dealMsg(Byte[] data, boolean ignore) {
        boolean deal = true;
        List<Byte[]> instructions = splitInstructions(data);
        if (instructions.size() > 1) {
            for (int i = 0; i < instructions.size(); i++) {
                dealMsgBySpilt(instructions.get(i), ignore);
            }
        } else {
            deal = dealMsgBySpilt(data, ignore);
        }
        int i = Integer.MIN_VALUE;
        if (deal) {
            i = (byte2int(data[4]) * 256) + byte2int(data[5]);
        }
        return i;
    }


    public boolean dealMsgBySpilt(Byte[] data, boolean ignore) {
        boolean deal = true;
        try {
            if (data[3] == (byte) 0x83) {
                if (data[4] == (byte) 0x33 && data[5] == (byte) 0xaa) {
                    SerialManage.getInstance().send("5A A5 06 83 33 aa 01 a5 a5");
                    Models.Companion.get().getStartEvent().setValue(false);
                    h.postDelayed(() -> SerialManage.getInstance().send("5A A5 03 82 4F 4B"), 100);
                } else {
                    deal = false;
                }
            } else if (data[3] == (byte) 0x82) {
                if (data[5] == (byte) 0x84) {
                    int i = byte2int(data[9]);
                    if (i > 0) {
                        StartEvent e = Models.Companion.get().getStartEvent();
                        if (!e.getValue()) {
                            e.postValue(true);
                        }
                    }
                    h.post(new Runnable() {
                        @Override
                        public void run() {
                            gotoPage(byte2int(data[9]), ignore);
                        }
                    });
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x4a) {
                    Event.rightRfEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x4b) {
                    Event.leftRfEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x4c) {
                    Event.rfShowEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x40) {
                    Event.leftTimeShowEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x41) {
                    Event.rightTimeShowEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x12) {
                    Event.workingModeEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 2) {
                    Event.rentEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x1a) {
                    Event.p1WorkEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x1b) {
                    Event.p2WorkEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x15) {
                    Event.leftProgressEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x16) {
                    Event.rightProgressEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x43) {
                    Event.sportModeEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x1c) {
                    Event.mfEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x1d) {
                    Event.sfEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x1e) {
                    Event.mtEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x1f) {
                    Event.stEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x22) {
                    Event.temp2Event.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x12 && data[5] == (byte) 0) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    FunctionCode.Current_Temp = decimalNumber;
                    SPHelper.getInstance(App.getApp(), true).putInt("temp", FunctionCode.Current_Temp).commit();
                    Event.tempEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x24) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.singleEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x26) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.doubleEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x12 && data[5] == (byte) 1) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.flowEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x27) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.aMaxEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x28) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.aMinEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x29) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.bMaxEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x2a) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.bMinEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x2b) {
                    Event.pwdEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x30) {
                    Event.handleSetEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x32) {
                    Event.flowStateEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x33) {
                    Event.tempStateEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x34) {
                    Event.levelStateEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x46) {
                    Const.num1High = byteToHex(data[6]) + byteToHex(data[7]);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x47) {
                    Const.num1Low = byteToHex(data[6]) + byteToHex(data[7]);
                    if (!TextUtils.isEmpty(Const.num1High)) {
                        long l = Long.parseLong(Const.num1High + Const.num1Low, 16);
                        Event.num1Event.postValue(l);
                    }
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x48) {
                    Event.time2Event.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x44) {
                    Const.num2High = byteToHex(data[6]) + byteToHex(data[7]);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x45) {
                    Const.num2Low = byteToHex(data[6]) + byteToHex(data[7]);
                    long l = Long.parseLong(Const.num2High + Const.num2Low, 16);
                    Event.num2Event.postValue(l);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 4) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.a1Event.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 5) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.a2Event.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 6) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.a3Event.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 7) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.b1Event.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 8) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.b2Event.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 9) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.b3Event.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x11) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.timeEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x10) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.leftTimeEvent.postValue(decimalNumber);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x17) {
                    Event.leftBEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x18) {
                    Event.rightBEvent.postValue(byte2int(data[7]));
                } else if (data[4] == (byte) 0x2f && data[5] >= 0 && data[5] < 4) {
                    FunctionCode.ver[data[5]] = byte2int(data[7]);
                    StringBuffer sb = new StringBuffer()
                            .append(FunctionCode.ver[0]).append(".")
                            .append(FunctionCode.ver[1]).append(".")
                            .append(FunctionCode.ver[2]).append(".")
                            .append(FunctionCode.ver[3]);
                    Const.ver = sb.toString();
                    SPHelper.getInstance(MyApp.getApp(), true).putString("ver", Const.ver).commit();
                    Utils.setCoreVersion(Const.ver);
                } else if (data[4] == (byte) 0x10 && data[5] == (byte) 0x0a) {
                    String tmp = byteToHex(data[6]) + byteToHex(data[7]);
                    int decimalNumber = Integer.parseInt(tmp, 16);
                    Event.vrefEvent.postValue(decimalNumber);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            deal = false;
        }

        return deal;
    }


    private void gotoPage(int index, boolean ignore) {
        Class c = null;
        if (index <= 8) {
            c = ModeActivity.class;
        } else if (index <= 12 || index == 15 || index == 16) {
            Const.mode = 2;
            c = WorkActivity.class;
        } else if (index <= 14 || index == 17 || index == 18) {
            Const.mode = 1;
            c = WorkActivity.class;
        } else if (index <= 22) {
            Const.mode = 3;
            c = WorkActivity.class;
        } else if (index <= 26) {
            c = SettingActivity.class;
        } else if (index <= 30) {
            //language
        } else if (index <= 34) {
            c = TempActivity.class;
        } else if (index <= 38) {
            c = FlowActivity.class;
        } else if (index <= 42) {
            c = VrefActivity.class;
        } else if (index <= 46) {
            c = PwdActivity.class;
        } else if (index <= 50) {
            c = WarnActivity.class;
            if (ignore) {
                Const.warned = true;
            }
        } else if (index <= 54) {
            c = RentActivity.class;
        } else if (index <= 58) {
//            c = WireActivity.class;
        } else if (index <= 62) {
            c = CardActivity.class;
        } else if (index <= 66) {
            c = ConfigActivity.class;
        }
        if (c == null || ignore) {
            if (c == null) {
                Log.e("tagg", "wrong type " + index);
            }
            return;
        }
        Intent i = new Intent(MyApp.getApp(), c);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        MyApp.getApp().startActivity(i);
    }

    public static List<Byte[]> splitInstructions(Byte[] data) {
        List<Byte[]> instructions = new ArrayList<>();

        if (data == null || data.length < 2) {
            return instructions;
        }

        int start = -1;  // 当前指令的起始位置
        int i = 0;

        while (i < data.length - 1) {
            // 检查当前字节和下一个字节是否是5A A5
            if ((data[i] & 0xFF) == 0x5A && (data[i + 1] & 0xFF) == 0xA5) {
                if (start != -1) {
                    // 将前一个指令添加到列表
                    Byte[] instruction = new Byte[i - start];
                    System.arraycopy(data, start, instruction, 0, instruction.length);
                    instructions.add(instruction);
                }
                // 设置新指令的起始位置
                start = i;
            }
            i++;
        }

        // 添加最后一个指令
        if (start != -1) {
            Byte[] instruction = new Byte[data.length - start];
            System.arraycopy(data, start, instruction, 0, instruction.length);
            instructions.add(instruction);
        }

        return instructions;
    }
}
